use godot::{
    classes::{Control, IControl, Label},
    prelude::*,
};
use zfwk_macros::sname;

use crate::misc::NodePool;


struct TextControlBlock {
    node: Gd<Label>,
    life_time: i64,
}

#[derive(GodotClass)]
#[class(init, base=Control)]
pub struct SplashTextManager {
    base: Base<Control>,
    #[export]
    text_prefab: Option<Gd<PackedScene>>,
    texts: Vec<TextControlBlock>,

    pool: NodePool<Label, 20>,
}

#[godot_api]
impl IControl for SplashTextManager {
    fn physics_process(&mut self, _delta: f64) {
        for text in &mut self.texts {
            let tick = sname!(c"tick");
            if text.node.has_method(&tick) {
                text.node.call(&tick, &[Variant::from(text.life_time)]);
            }

            if text.life_time == 0 {
                self.pool.free(text.node.clone());
            }
            text.life_time -= 1;
        }
        self.texts.retain(|x| x.life_time >= 0);
    }
}

#[godot_api]
impl SplashTextManager {
    #[func]
    pub fn add_text(&mut self, text: GString, color: Color, position: Vector2, life: i64) {
        let mut label = self.pool.obtain(&self.text_prefab);
        label.set_text(&text);
        if let Some(mut ls) = label.get_label_settings() {
            ls.set_font_color(color);
            ls.set_outline_color(color.darkened(0.6));
        } else {
            label.add_theme_color_override(&sname!(c"font_color"), color);
            label.add_theme_color_override(&sname!(c"font_outline_color"), color.darkened(0.6));
        }
        self.base_mut().add_child(&label);
        label.set_position(position);
        self.texts.push(TextControlBlock {
            node: label,
            life_time: life,
        });
    }
}
